using System.Text;
using RSCore.Files;

namespace RSCore;

public class KeyConverter143 : KeyConverter
{
	public KeyConverter143()
	{
		_sb = new StringBuilder(32);
		_entryTypeMapping = new()
		{
			["ItemName"] = (EntryType.Item, "DisplayName"),
			["ItemTooltip"] = (EntryType.Item, "Tooltip"),
			["NPCName"] = (EntryType.NPC, "DisplayName"),
			["ProjectileName"] = (EntryType.Projectile, "DisplayName"),
			["DamageClassName"] = (EntryType.DamageClass, "DisplayName"),
			["Prefix"] = (EntryType.Prefix, "DisplayName"),
			["InfoDisplayName"] = (EntryType.InfoDisplay, "DisplayName"),
			["BiomeName"] = (EntryType.Biome, "DisplayName"),
			["Containers"] = (EntryType.Tile, "ContainerName"),
			["MapObject"] = (EntryType.Tile, "MapEntry"),
			["BuffName"] = (EntryType.Buff, "DisplayName"),
			["BuffDescription"] = (EntryType.Buff, "Description"),
			["TownNPCMood"] = (EntryType.TownNPCMood, string.Empty),
		};
		_reverseMapping = _entryTypeMapping.ToDictionary(
		p => p.Value,
		p => p.Key);
	}

	public override KeyData Convert(string key)
	{
		key = Normalize(key);
		var match = SplitKey(key);
		if (match.Success && _entryTypeMapping.TryGetValue(match.Groups[1].Value, out var pair))
		{
			if (pair.Type == EntryType.TownNPCMood)
			{
				pair.Property = match.Groups[3].Value;
			}

			Type type = pair.Type.GetFileType();
			if (type.HasProperty(pair.Property) | type.IsAssignableTo(typeof(IExtensibleFile)))
			{
				return new KeyData(match.Groups[2].Value, pair.Type, pair.Property);
			}
		}

		return new KeyData(key, EntryType.None, string.Empty);
	}

	public override string Convert(KeyData key)
	{
		if (key.EntryType == EntryType.None)
		{
			return key.Identity;
		}

		if (key.EntryType == EntryType.TownNPCMood && key.Property != "MapEntry")
		{
			return _sb.Clear().Append(nameof(EntryType.TownNPCMood)).Append('.')
				.Append(key.Identity).Append('.')
				.Append(key.Property)
				.ToString();
		}

		if (key.EntryType == EntryType.Tile)
		{
			return _sb.Clear().Append("MapObject.").Append(key.Identity).Append('.')
				.Append(key.Property)
				.ToString();
		}

		return _sb.Clear().Append(_reverseMapping[(key.EntryType, key.Property)]).Append('.')
				.Append(key.Identity)
				.ToString();
	}

	private readonly Dictionary<string, (EntryType Type, string Property)> _entryTypeMapping;

	private readonly Dictionary<(EntryType Type, string Property), string> _reverseMapping;

	private StringBuilder _sb;
}